{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: \n",
      "The text.latex.preview rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.\n",
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: \n",
      "The mathtext.fallback_to_cm rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.\n",
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: Support for setting the 'mathtext.fallback_to_cm' rcParam is deprecated since 3.3 and will be removed two minor releases later; use 'mathtext.fallback : 'cm' instead.\n",
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: \n",
      "The validate_bool_maybe_none function was deprecated in Matplotlib 3.3 and will be removed two minor releases later.\n",
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: \n",
      "The savefig.jpeg_quality rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.\n",
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: \n",
      "The keymap.all_axes rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.\n",
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: \n",
      "The animation.avconv_path rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.\n",
      "In C:\\Users\\Han\\.conda\\envs\\my_project1\\lib\\site-packages\\matplotlib\\mpl-data\\stylelib\\_classic_test.mplstyle: \n",
      "The animation.avconv_args rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import graphviz\n",
    "import lingam\n",
    "from lingam.utils import make_dot\n",
    "import logging\n",
    "import dowhy\n",
    "from dowhy import CausalModel\n",
    "from semopy import Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_excel(r\"C:\\\\df.xlsx\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index(['wvs', 'country', 'oecd', 'id', 'year', 'subjective', 'low', 'middle',\n",
       "       'high', 'income', 'age', 'sex', 'marriage', 'education', 'urban',\n",
       "       'religion', 'ideology', 'Trust_Government', 'Trust_Company',\n",
       "       'Private_vs_Government', 'Financial_Satisfaction', 'region'],\n",
       "      dtype='object')"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.columns.unique()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define the SEM model\n",
    "model_desc = \"\"\"\n",
    "Private_vs_Government ~ Trust_Government + Trust_Company\n",
    "Trust_Government ~ income + age + sex + marriage + education + urban + religion + ideology\n",
    "Trust_Government ~ Financial_Satisfaction\n",
    "Trust_Company ~ income + age + sex + marriage + education + urban + religion + ideology\n",
    "Trust_Company ~ Financial_Satisfaction\n",
    "Private_vs_Government ~ income + age + sex + marriage + education + urban + religion + ideology + Financial_Satisfaction\n",
    "\"\"\"\n",
    "\n",
    "# Create and fit the model\n",
    "model = Model(model_desc)\n",
    "results = model.fit(df)\n",
    "params = model.inspect()\n",
    "\n",
    "# Function to visualize the SEM model with parameter estimates\n",
    "def visualize_sem_with_params(model, params, path=\"sem_graph\", width=\"80\", height=\"180\", fontsize=\"18\"):\n",
    "    dot = graphviz.Digraph(comment='SEM Model with Parameters')\n",
    "    dot.attr(size=f\"{width},{height}\", ratio='auto')\n",
    "\n",
    "    # List of variables to be shaped as rectangles\n",
    "    rectangle_vars = {'income', 'age', 'sex', 'marriage', 'education', 'urban','religion', 'ideology', 'Financial_Satisfaction'}\n",
    "\n",
    "    # Adding nodes with custom shapes\n",
    "    for var in model.vars:\n",
    "        if var in rectangle_vars:\n",
    "            dot.node(var, var, shape='box', color='red' if var == 'Financial_Satisfaction' else 'black', fontcolor='red' if var == 'financial_satis' else 'black')\n",
    "        else:\n",
    "            dot.node(var, var, shape='ellipse')  # Default shape as ellipse\n",
    "\n",
    "    # Define custom style for edges and labels\n",
    "    edge_style = {'penwidth': '3.0'}\n",
    "    label_style = {'fontsize': fontsize}\n",
    "\n",
    "    # Adding edges with parameter estimates and p-values\n",
    "    for index, row in params.iterrows():\n",
    "        if row['op'] == '~':\n",
    "            estimate = round(row['Estimate'], 3)\n",
    "            p_value = round(row['p-value'], 3)\n",
    "            significance = '***' if p_value < 0.01 else '**' if p_value < 0.05 else ''\n",
    "            label = f'est: {estimate}, p: {p_value} {significance}'\n",
    "\n",
    "            is_inequality_edge = 'Work_hours' in [row['lval'], row['rval']]\n",
    "            if is_inequality_edge:\n",
    "                edge_style['color'] = 'red'\n",
    "                edge_style['fontcolor'] = 'red'\n",
    "            else:\n",
    "                edge_style['color'] = 'black'\n",
    "                edge_style['fontcolor'] = 'black'\n",
    "\n",
    "            dot.edge(row['rval'], row['lval'], label=label, **edge_style, **label_style)\n",
    "\n",
    "    # Save and render the graph\n",
    "    dot.render(path, view=True)\n",
    "\n",
    "# Visualize the SEM model with specific nodes as rectangles\n",
    "visualize_sem_with_params(model, params, \"sem_example_with_params\", width=\"80\", height=\"180\", fontsize=\"18\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define the SEM model\n",
    "model_desc = \"\"\"\n",
    "Private_vs_Government ~ Trust_Government + Trust_Company\n",
    "Trust_Government ~ income + age + sex + marriage + education + urban + religion + ideology\n",
    "Trust_Government ~ Financial_Satisfaction\n",
    "Trust_Company ~ income + age + sex + marriage + education + urban + religion + ideology\n",
    "Trust_Company ~ Financial_Satisfaction\n",
    "Private_vs_Government ~ income + age + sex + marriage + education + urban + religion + ideology + Financial_Satisfaction\n",
    "\"\"\"\n",
    "\n",
    "\n",
    "# Create and fit the model\n",
    "model = Model(model_desc)\n",
    "results = model.fit(df)\n",
    "params = model.inspect()\n",
    "\n",
    "# Function to visualize the SEM model with parameter estimates\n",
    "def visualize_focused_sem_with_params(model, params, focus_vars, path=\"focused_sem_graph\", width=\"80\", height=\"100\", fontsize=\"18\"):\n",
    "    dot = graphviz.Digraph(comment='Focused SEM Model with Parameters')\n",
    "    dot.attr(size=f\"{width},{height}\", ratio='auto')\n",
    "\n",
    "    # Define the set of variables to focus on\n",
    "    focus_set = set(focus_vars)\n",
    "\n",
    "    # Adding nodes for the focused variables\n",
    "    for var in focus_set:\n",
    "        dot.node(var, var, shape='ellipse')\n",
    "\n",
    "    # Adding edges with parameter estimates for the focused variables\n",
    "    for index, row in params.iterrows():\n",
    "        if row['op'] == '~' and {row['lval'], row['rval']}.issubset(focus_set):\n",
    "            estimate = round(row['Estimate'], 3)\n",
    "            p_value = round(row['p-value'], 3)\n",
    "            significance = '***' if p_value < 0.01 else '**' if p_value < 0.05 else ''\n",
    "            label = f'est: {estimate}, p: {p_value} {significance}'\n",
    "            dot.edge(row['rval'], row['lval'], label=label, fontsize=fontsize)\n",
    "\n",
    "    # Save and render the graph\n",
    "    dot.render(path, view=True)\n",
    "\n",
    "# Specify the focus variables\n",
    "focus_vars = ['Trust_Government', 'Financial_Satisfaction', 'Trust_Company', 'Private_vs_Government']\n",
    "\n",
    "# Visualize the SEM model focused on specified variables\n",
    "visualize_focused_sem_with_params(model, params, focus_vars, \"focused_sem_example\", width=\"80\", height=\"100\", fontsize=\"18\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                     lval  op                    rval  Estimate  Std. Err  \\\n",
      "0        Trust_Government   ~                  income  0.000416  0.000651   \n",
      "1        Trust_Government   ~                     age  0.003905  0.000935   \n",
      "2        Trust_Government   ~                     sex  0.004993  0.002841   \n",
      "3        Trust_Government   ~                marriage  0.027031  0.003039   \n",
      "4        Trust_Government   ~               education -0.011312  0.002032   \n",
      "5        Trust_Government   ~                   urban  0.006886  0.000580   \n",
      "6        Trust_Government   ~                religion -0.064971  0.003093   \n",
      "7        Trust_Government   ~                ideology  0.002858  0.000596   \n",
      "8        Trust_Government   ~  Financial_Satisfaction  0.034992  0.000550   \n",
      "9           Trust_Company   ~                  income  0.001082  0.000591   \n",
      "10          Trust_Company   ~                     age -0.003815  0.000850   \n",
      "11          Trust_Company   ~                     sex -0.003306  0.002583   \n",
      "12          Trust_Company   ~                marriage  0.005968  0.002762   \n",
      "13          Trust_Company   ~               education -0.006145  0.001847   \n",
      "14          Trust_Company   ~                   urban  0.000181  0.000527   \n",
      "15          Trust_Company   ~                religion  0.003864  0.002811   \n",
      "16          Trust_Company   ~                ideology  0.002323  0.000542   \n",
      "17          Trust_Company   ~  Financial_Satisfaction  0.030817  0.000500   \n",
      "18  Private_vs_Government   ~        Trust_Government  0.195188  0.004499   \n",
      "19  Private_vs_Government   ~           Trust_Company -0.146639  0.004950   \n",
      "20  Private_vs_Government   ~                  income -0.005522  0.001966   \n",
      "21  Private_vs_Government   ~                     age -0.027957  0.002825   \n",
      "22  Private_vs_Government   ~                     sex -0.023710  0.008584   \n",
      "23  Private_vs_Government   ~                marriage  0.052094  0.009182   \n",
      "24  Private_vs_Government   ~               education -0.057918  0.006138   \n",
      "25  Private_vs_Government   ~                   urban  0.009531  0.001753   \n",
      "26  Private_vs_Government   ~                religion  0.061240  0.009348   \n",
      "27  Private_vs_Government   ~                ideology  0.003047  0.001801   \n",
      "28  Private_vs_Government   ~  Financial_Satisfaction -0.032932  0.001677   \n",
      "29          Trust_Company  ~~           Trust_Company  0.741958  0.001563   \n",
      "30       Trust_Government  ~~        Trust_Government  0.897982  0.001891   \n",
      "31  Private_vs_Government  ~~   Private_vs_Government  8.196062  0.017262   \n",
      "\n",
      "       z-value       p-value  \n",
      "0     0.638985  5.228328e-01  \n",
      "1     4.176016  2.966593e-05  \n",
      "2     1.757460  7.883943e-02  \n",
      "3     8.895041  0.000000e+00  \n",
      "4    -5.568199  2.573859e-08  \n",
      "5    11.870042  0.000000e+00  \n",
      "6   -21.007105  0.000000e+00  \n",
      "7     4.795053  1.626314e-06  \n",
      "8    63.583912  0.000000e+00  \n",
      "9     1.829079  6.738774e-02  \n",
      "10   -4.488579  7.169968e-06  \n",
      "11   -1.279985  2.005503e-01  \n",
      "12    2.160591  3.072698e-02  \n",
      "13   -3.327955  8.748600e-04  \n",
      "14    0.342356  7.320832e-01  \n",
      "15    1.374574  1.692637e-01  \n",
      "16    4.287380  1.807925e-05  \n",
      "17   61.605600  0.000000e+00  \n",
      "18   43.381914  0.000000e+00  \n",
      "19  -29.625153  0.000000e+00  \n",
      "20   -2.808833  4.972150e-03  \n",
      "21   -9.895978  0.000000e+00  \n",
      "22   -2.762128  5.742593e-03  \n",
      "23    5.673582  1.398418e-08  \n",
      "24   -9.436474  0.000000e+00  \n",
      "25    5.437015  5.418071e-08  \n",
      "26    6.550837  5.721557e-11  \n",
      "27    1.692250  9.059836e-02  \n",
      "28  -19.637291  0.000000e+00  \n",
      "29  474.799431  0.000000e+00  \n",
      "30  474.799431  0.000000e+00  \n",
      "31  474.799431  0.000000e+00  \n"
     ]
    }
   ],
   "source": [
    "# Define the SEM model\n",
    "model_desc = \"\"\"\n",
    "Private_vs_Government ~ Trust_Government + Trust_Company\n",
    "Trust_Government ~ income + age + sex + marriage + education + urban + religion + ideology\n",
    "Trust_Government ~ Financial_Satisfaction\n",
    "Trust_Company ~ income + age + sex + marriage + education + urban + religion + ideology\n",
    "Trust_Company ~ Financial_Satisfaction\n",
    "Private_vs_Government ~ income + age + sex + marriage + education + urban + religion + ideology + Financial_Satisfaction\n",
    "\"\"\"\n",
    "\n",
    "\n",
    "# Create and fit the model\n",
    "model = Model(model_desc)\n",
    "results = model.fit(df)\n",
    "\n",
    "# Inspect the model's results\n",
    "params = model.inspect()\n",
    "\n",
    "# Display the results\n",
    "print(params)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
